package top.truism.auth.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import top.truism.auth.config.PermissionMetaCollector;
import top.truism.auth.enums.UserLevel;
import top.truism.auth.permission.AuthorizeVerifyResolver;
import top.truism.auth.permission.MetaInfo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Objects;

public class AuthorizeInterceptor extends HandlerInterceptorAdapter {

  @Autowired private AuthorizeVerifyResolver authorizeVerifyResolver;

  @Autowired private PermissionMetaCollector permissionMetaCollector;

  public AuthorizeInterceptor() {

  }

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    if (handler instanceof HandlerMethod) {
      HandlerMethod handlerMethod = (HandlerMethod) handler;
      Method method = handlerMethod.getMethod();
      Class cla = method.getDeclaringClass();
      String identity = cla.getName() + "#" + method.getName();
      MetaInfo metaInfo = permissionMetaCollector.findMetaInfo(identity);
      if (Objects.nonNull(metaInfo)) {
        return this.handleMeta(request, response, method, metaInfo);
      } else {
        // 接口没有设置权限
        return this.authorizeVerifyResolver.handleLogin(request, response, null);
      }
    } else {
      return authorizeVerifyResolver.handleNoyHandlerMethod(request, response, null);
    }
  }

  @Override
  public void postHandle(
      HttpServletRequest request,
      HttpServletResponse response,
      Object handler,
      ModelAndView modelAndView)
      throws Exception {
    authorizeVerifyResolver.handlePostHandler(request, response, handler, modelAndView);
  }

  @Override
  public void afterCompletion(
      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
    this.authorizeVerifyResolver.handleAfterCompletion(request, response, handler, ex);
  }

  private boolean handleMeta(
      HttpServletRequest request, HttpServletResponse response, Method method, MetaInfo metaInfo) {
    UserLevel userLevel = metaInfo.getUserLevel();
    switch (userLevel) {
      case Tourist:
      case Login:
        return authorizeVerifyResolver.handleLogin(request, response, metaInfo);
      case Group:
        return authorizeVerifyResolver.handleGroup(request, response, metaInfo);
      case Admin:
        return authorizeVerifyResolver.handleAdmin(request, response, metaInfo);
      default:
        return true;
    }
  }
}
